home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / doom / quake.zip / HIPGRAPL.ZIP / COMBAT.QC < prev    next >
Text File  |  1997-02-09  |  7KB  |  330 lines

  1.  
  2. void() T_MissileTouch;
  3. void() info_player_start;
  4. void(entity targ, entity attacker) ClientObituary;
  5.  
  6. void() monster_death_use;
  7.  
  8. //============================================================================
  9.  
  10. /*
  11. ============
  12. CanDamage
  13.  
  14. Returns true if the inflictor can directly damage the target.  Used for
  15. explosions and melee attacks.
  16. ============
  17. */
  18. float(entity targ, entity inflictor) CanDamage =
  19. {
  20. // bmodels need special checking because their origin is 0,0,0
  21.     if (targ.movetype == MOVETYPE_PUSH)
  22.     {
  23.         traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
  24.         if (trace_fraction == 1)
  25.             return TRUE;
  26.         if (trace_ent == targ)
  27.             return TRUE;
  28.         return FALSE;
  29.     }
  30.  
  31.     traceline(inflictor.origin, targ.origin, TRUE, self);
  32.     if (trace_fraction == 1)
  33.         return TRUE;
  34.     traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
  35.     if (trace_fraction == 1)
  36.         return TRUE;
  37.     traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
  38.     if (trace_fraction == 1)
  39.         return TRUE;
  40.     traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
  41.     if (trace_fraction == 1)
  42.         return TRUE;
  43.     traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
  44.     if (trace_fraction == 1)
  45.         return TRUE;
  46.  
  47.     return FALSE;
  48. };
  49.  
  50.  
  51. /*
  52. ============
  53. Killed
  54. ============
  55. */
  56. void(entity targ, entity attacker) Killed =
  57. {
  58.     local entity oself;
  59.  
  60.     oself = self;
  61.     self = targ;
  62.  
  63.     if (self.health < -99)
  64.         self.health = -99;        // don't let sbar look bad if a player
  65. //MED
  66.    if (self.charmed)
  67.       {
  68.       self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  69.       }
  70. //      self.effects = self.effects - EF_BRIGHTFIELD;
  71.  
  72.     if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
  73.     {    // doors, triggers, etc
  74.         self.th_die ();
  75.         self = oself;
  76.         return;
  77.     }
  78.  
  79.     self.enemy = attacker;
  80.  
  81. // bump the monster counter
  82.    if (self.flags & FL_MONSTER)
  83.     {
  84.       killed_monsters = killed_monsters + 1;
  85.         WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
  86.     }
  87.  
  88.     ClientObituary(self, attacker);
  89.  
  90.     self.takedamage = DAMAGE_NO;
  91.     self.touch = SUB_Null;
  92.  
  93.     monster_death_use();
  94.     self.th_die ();
  95.  
  96.     self = oself;
  97. };
  98.  
  99.  
  100. /*
  101. ============
  102. T_Damage
  103.  
  104. The damage is coming from inflictor, but get mad at attacker
  105. This should be the only function that ever reduces health.
  106. ============
  107. */
  108. //MED 01/10/97 added empathyused variable
  109. float empathyused;
  110. void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
  111. {
  112.     local    vector    dir;
  113.     local    entity    oldself;
  114.     local    float    save;
  115.     local    float    take;
  116.  
  117.     if (!targ.takedamage)
  118.         return;
  119.  
  120.    if (discharged && targ.wetsuit_finished )
  121.       return;
  122. //MED moved damage_attacker down a bit
  123. /*
  124.    dprint("netname = ");
  125.    dprint(attacker.netname);
  126.    dprint(" classname = ");
  127.    dprint(attacker.classname);
  128.    dprint(" classname = ");
  129.    dprint(inflictor.classname);
  130.    dprint("\n");
  131. */
  132. // check for quad damage powerup on the attacker
  133.     if (attacker.super_damage_finished > time)
  134.         damage = damage * 4;
  135.  
  136.  
  137. //MED
  138. //check for empathy shields
  139.    if ((targ.items2 & HIP_IT_EMPATHY_SHIELDS) && !(inflictor.items2 & HIP_IT_EMPATHY_SHIELDS) && (targ != attacker))
  140.       {
  141.       empathyused = 1;
  142.       damage = damage/2;
  143.       T_Damage (attacker,targ,targ,damage);
  144.       empathyused = 0;
  145.       }
  146. //MED
  147. // used by buttons and triggers to set activator for target firing
  148.     damage_attacker = attacker;
  149.  
  150. //MED
  151. // used to keep track of what hit us
  152.    damage_inflictor = inflictor;
  153.  
  154. // save damage based on the target's armor level
  155.  
  156.     save = ceil(targ.armortype*damage);
  157.     if (save >= targ.armorvalue)
  158.     {
  159.         save = targ.armorvalue;
  160.         targ.armortype = 0;    // lost all armor
  161.       targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
  162.    }
  163.  
  164.     targ.armorvalue = targ.armorvalue - save;
  165.     take = ceil(damage-save);
  166.  
  167. // add to the damage total for clients, which will be sent as a single
  168. // message at the end of the frame
  169. // FIXME: remove after combining shotgun blasts?
  170.     if (targ.flags & FL_CLIENT)
  171.     {
  172.         targ.dmg_take = targ.dmg_take + take;
  173.         targ.dmg_save = targ.dmg_save + save;
  174.         targ.dmg_inflictor = inflictor;
  175.     }
  176.  
  177. // figure momentum add
  178.     if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
  179.     {
  180.         dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
  181.         dir = normalize(dir);
  182.         targ.velocity = targ.velocity + dir*damage*8;
  183.     }
  184.  
  185. // check for godmode or invincibility
  186.     if (targ.flags & FL_GODMODE)
  187.         return;
  188.     if (targ.invincible_finished >= time)
  189.     {
  190.         if (self.invincible_sound < time)
  191.         {
  192.             sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  193.             self.invincible_sound = time + 2;
  194.         }
  195.         return;
  196.     }
  197. //MED
  198.    if (targ.items2 & HIP_IT_EMPATHY_SHIELDS)
  199.     {
  200.       if (self.empathy_sound < time)
  201.         {
  202.          sound (targ, CHAN_ITEM, "hipitems/empathy2.wav", 1, ATTN_NORM);
  203.          self.empathy_sound = time + 0.5;
  204.         }
  205.     }
  206.  
  207. // team play damage avoidance
  208.     if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) )
  209.         return;
  210.  
  211. // do the damage
  212.     targ.health = targ.health - take;
  213.  
  214.     if (targ.health <= 0)
  215.     {
  216.         Killed (targ, attacker);
  217.         return;
  218.     }
  219.  
  220. // react to the damage
  221.     oldself = self;
  222.     self = targ;
  223.  
  224. //MED 10/17/96 added charmed stuff
  225.     if ( (self.flags & FL_MONSTER) && attacker != world)
  226.     {
  227.     // get mad unless of the same class (except for soldiers)
  228.       if (self != attacker && attacker != self.enemy && (self.charmer!=attacker))
  229.         {
  230.             if ( (self.classname != attacker.classname)
  231.          || (self.classname == "monster_army" ) || (self.classname == "monster_armagon" ) )
  232.             {
  233.                 if (self.enemy.classname == "player")
  234.                     self.oldenemy = self.enemy;
  235.                 self.enemy = attacker;
  236.                 FoundTarget ();
  237.             }
  238.         }
  239.     }
  240.  
  241.     if (self.th_pain)
  242.     {
  243.         self.th_pain (attacker, take);
  244.     // nightmare mode monsters don't go into pain frames often
  245.         if (skill == 3)
  246.             self.pain_finished = time + 5;
  247.     }
  248.  
  249.     self = oldself;
  250. };
  251.  
  252. /*
  253. ============
  254. T_RadiusDamage
  255. ============
  256. */
  257. void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
  258. {
  259.     local    float     points;
  260.     local    entity    head;
  261.     local    vector    org;
  262.  
  263.     head = findradius(inflictor.origin, damage+40);
  264.  
  265.     while (head)
  266.     {
  267.         if (head != ignore)
  268.         {
  269.             if (head.takedamage)
  270.             {
  271.                 org = head.origin + (head.mins + head.maxs)*0.5;
  272.                 points = 0.5*vlen (inflictor.origin - org);
  273.                 if (points < 0)
  274.                     points = 0;
  275.                 points = damage - points;
  276.                 if (head == attacker)
  277.                     points = points * 0.5;
  278.                 if (points > 0)
  279.                 {
  280.                     if (CanDamage (head, inflictor))
  281.                     {    // shambler takes half damage from all explosions
  282.                         if (head.classname == "monster_shambler")
  283.                             T_Damage (head, inflictor, attacker, points*0.5);
  284.                         else
  285.                             T_Damage (head, inflictor, attacker, points);
  286.                     }
  287.                 }
  288.             }
  289.         }
  290.         head = head.chain;
  291.     }
  292. };
  293.  
  294. /*
  295. ============
  296. T_BeamDamage
  297. ============
  298. */
  299. void(entity attacker, float damage) T_BeamDamage =
  300. {
  301.     local    float     points;
  302.     local    entity    head;
  303.  
  304.     head = findradius(attacker.origin, damage+40);
  305.  
  306.     while (head)
  307.     {
  308.         if (head.takedamage)
  309.         {
  310.             points = 0.5*vlen (attacker.origin - head.origin);
  311.             if (points < 0)
  312.                 points = 0;
  313.             points = damage - points;
  314.             if (head == attacker)
  315.                 points = points * 0.5;
  316.             if (points > 0)
  317.             {
  318.                 if (CanDamage (head, attacker))
  319.                 {
  320.                     if (head.classname == "monster_shambler")
  321.                         T_Damage (head, attacker, attacker, points*0.5);
  322.                     else
  323.                         T_Damage (head, attacker, attacker, points);
  324.                 }
  325.             }
  326.         }
  327.         head = head.chain;
  328.     }
  329. };
  330.